--Ejercicio 1
--Los tipos se pueden ver con :t
{-
Main> :t null
null :: [a] -> Bool
Main> :t head
head :: [a] -> a
Main> :t tail
tail :: [a] -> [a]
Main> :t init
init :: [a] -> [a]
Main> :t last
last :: [a] -> a
Main> :t take
take :: Int -> [a] -> [a]
Main> :t drop
drop :: Int -> [a] -> [a]
Main> :t (++)
(++) :: [a] -> [a] -> [a]
Main> :t concat
concat :: [[a]] -> [a]
Main> :t (!!)
(!!) :: [a] -> Int -> a
Main> :t elem
elem :: Eq a => a -> [a] -> Bool
-}

--Ejercicio 2
--a)
valorAbsoluto :: Float->Float
valorAbsoluto f | f < 0 = -f 
				| otherwise = f
	
--b)	
bisiesto :: Int -> Bool
bisiesto a  | ((a `mod` 400)==0) = True
			| ((a `mod` 100)==0) = False
			| ((a `mod` 4)==0) = True
		    | otherwise = False

--c)			
factorial :: Int->Int
factorial n | (n == 0) = 1
			| (n > 0) = n * (factorial (n-1))
			
--cantDivPrimos :: Int -> Int

--Ejercicio 3
--a)
inverso::Float -> Maybe Float
inverso 0 = Nothing
inverso f = Just (1/f)

--b)
aEntero:: Either Int Bool->Int
aEntero (Left a) = a
aEntero (Right b) | b = 1
				  | otherwise = 0

--Ejercicio 4
--a)
limpiar::String->String->String
limpiar [] y = y
limpiar (x:xs) y = limpiar xs (limpiarAux x y)

limpiarAux::Char->String->String
limpiarAux c [] = []
limpiarAux c (s:ss) = if (c==s) then limpiarAux c ss else (s:(limpiarAux c ss))

--b)
difPromedio::[Float]->[Float]
difPromedio [] = []
difPromedio fs = difPromedioAux fs (promedio fs)

difPromedioAux ::[Float]->Float->[Float]
difPromedioAux [] p = []
difPromedioAux (f:fs) p = (f-p):difPromedioAux fs p

promedio ::[Float]-> Float
promedio fs =  (sum fs) / fromIntegral(length fs)

--c)
todosIguales::[Int]->Bool
todosIguales [] = True
todosIguales (i:[]) = True
todosIguales (i:is) = i == head is && todosIguales is

--Ejercicio 5
data AB a = Nil | Bin (AB a) a (AB a) deriving Show

--a)
nullTree:: AB a ->Bool
nullTree Nil = True
nullTree (Bin a b c) = False

--b)
negTree::AB Bool -> AB Bool
negTree Nil = Nil
negTree (Bin a b c) = Bin (negTree a) (not b) (negTree c)

--C)
prodTree:: AB Int->Int
prodTree Nil = 1
prodTree (Bin a b c) = (prodTree a) * b * (prodTree c)

